package com.unittec.drainage.provider.auth.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.unittec.drainage.provider.auth.util.FindsDepartsChildrenUtil;
import com.unittec.drainage.provider.auth.util.YouBianCodeUtil;
import com.unittec.drainage.provider.auth.dto.SysDepartTree;
import com.unittec.drainage.provider.auth.entity.SysDepart;
import com.unittec.drainage.provider.auth.entity.SysUserDepart;
import com.unittec.drainage.provider.auth.mapper.SysDepartMapper;
import com.unittec.drainage.provider.auth.mapper.SysUserMapper;
import com.unittec.drainage.provider.root.ServiceRoot;
import com.unittec.drainage.provider.utils.CopyUtils;
import com.unittec.drainage.provider.utils.UUIDUtils;
import com.unittec.drainage.sdk.auth.domain.SysDepartDto;
import com.unittec.drainage.sdk.root.common.CommonConstant;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author Jason
 * @description 部门Service
 * @date 2019/11/07
 */
@Service
public class SysDepartService extends ServiceRoot<SysDepartMapper, SysDepart> {

    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private SysUserDepartService sysUserDepartService;

    /**
     * 查询所有的部门数据,以树结构形式返回
     *
     * @return
     */
    public List<SysDepartTree> queryTreeList(Boolean containUserFlag) {

        List<SysDepartDto> unionList =new ArrayList<>();

        LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<SysDepart>();
        query.eq(SysDepart::getDelFlag, CommonConstant.DELETE_NO);
        query.orderByAsc(SysDepart::getDepartOrder);
        List<SysDepart> list = this.list(query);
        for (SysDepart sysDepart : list) {
            SysDepartDto departDto = new SysDepartDto();
            CopyUtils.copyProperties(sysDepart, departDto);
            departDto.setUserType("0");
            unionList.add(departDto);
        }
        List<SysDepartDto> userDeptInfo = new ArrayList<>();
        if (containUserFlag != null && containUserFlag) {
            List<String> deptIds = new ArrayList<>();
            for (SysDepart sysDepart : list) {
                deptIds.add(sysDepart.getId());
            }
            if (deptIds.size() > 0) {
                List<Map<String, Object>> deptUserList = this.getBaseMapper().getUserInfoByDeptIds(deptIds);
                if (deptUserList != null && deptUserList.size() > 0) {
                    for (SysDepart sysDepart : list) {
                        for (Map<String, Object> map : deptUserList) {
                            String user_id = String.valueOf(map.get("user_id"));
                            String user_name = String.valueOf(map.get("user_name"));
                            String real_name = String.valueOf(map.get("real_name"));
                            String dept_id = String.valueOf(map.get("dept_id"));
                            if (sysDepart.getId().equalsIgnoreCase(dept_id)) {
                                SysDepartDto entity = new SysDepartDto();
                                entity.setId(user_id);
                                entity.setDepartName(real_name);
                                entity.setParentId(dept_id);
                                entity.setUserType("1");
                                userDeptInfo.add(entity);
                            }

                        }
                    }
                }
            }

        }
        if (userDeptInfo.size() > 0) {
            unionList.addAll(userDeptInfo);
        }

        List<SysDepartTree> listResult = FindsDepartsChildrenUtil.wrapTreeDataToTreeList4(unionList);
        return listResult;
    }

    /**
     * 根据部门名称搜索相关的部门数据
     *
     * @param departName
     * @return
     */
    public List<SysDepartTree> searhBy(String departName) {
        LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<SysDepart>();
        query.eq(SysDepart::getDelFlag, CommonConstant.DELETE_NO);
        query.like(SysDepart::getDepartName, departName);
        query.orderByAsc(SysDepart::getDepartOrder);
        List<SysDepart> list = this.list(query);
        SysDepartTree tree = new SysDepartTree();
        List<SysDepartTree> newList = new ArrayList<SysDepartTree>();
        if (list.size() > 0) {
            for (SysDepart depart : list) {
                tree = new SysDepartTree(depart);
                tree.setChildren(null);
                newList.add(tree);
            }
        }
        return newList;
    }

    @Transactional(rollbackFor = Exception.class)
    public void saveDepartData(SysDepart sysDepart) {
        if (sysDepart != null) {
            if (sysDepart.getParentId() == null) {
                sysDepart.setParentId("");
            }
            sysDepart.setId(UUIDUtils.getId());
            String parentId = sysDepart.getParentId();
            String[] codeArray = generateOrgCode(parentId);
            sysDepart.setOrgCode(codeArray[0]);
            sysDepart.setOrgType(codeArray[1]);
            sysDepart.setStatus(CommonConstant.STATUS_0);
            sysDepart.setDelFlag(CommonConstant.DELETE_NO);
            this.save(sysDepart);
        }

    }

    /**
     * 批量删除部门
     *
     * @param ids
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteBatchWithChildren(List<String> ids) {
        List<String> idList = new ArrayList<>();
        for (String id : ids) {
            idList.add(id);
            this.checkChildrenExists(id, idList);
        }
        this.removeByIds(idList);
    }

    private void checkChildrenExists(String id, List<String> idList) {
        LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<SysDepart>();
        query.eq(SysDepart::getParentId, id);
        List<SysDepart> departList = this.list(query);
        if (departList != null && departList.size() > 0) {
            for (SysDepart depart : departList) {
                idList.add(depart.getId());
                this.checkChildrenExists(depart.getId(), idList);
            }
        }
    }

    /**
     * saveDepartData的调用方法,生成部门编码和部门类型
     *
     * @param parentId
     * @return
     */
    private String[] generateOrgCode(String parentId) {
        LambdaQueryWrapper<SysDepart> query1 = new LambdaQueryWrapper<SysDepart>();
        LambdaQueryWrapper<SysDepart> query2 = new LambdaQueryWrapper<SysDepart>();
        String[] strArray = new String[2];
        List<SysDepart> departList = new ArrayList<>();
        String orgCode = "";
        String orgType = "";
        if (StringUtils.isBlank(parentId)) {
            query2.eq(SysDepart::getParentId, "");
            query2.orderByDesc(SysDepart::getOrgCode);
            departList = this.list(query2);
            if (departList == null || departList.size() == 0) {
                strArray[0] = YouBianCodeUtil.getNextYouBianCode(null);
                strArray[1] = "0";
                return strArray;
            } else {
                SysDepart depart = departList.get(0);
                orgCode = YouBianCodeUtil.getNextYouBianCode(depart.getOrgCode());
                orgType = "0";
            }
        } else {
            query1.eq(SysDepart::getParentId, parentId);
            query1.orderByDesc(SysDepart::getOrgCode);
            List<SysDepart> parentList = this.list(query1);
            SysDepart depart = this.getById(parentId);
            String parentCode = depart.getOrgCode();
            if (parentList == null || parentList.size() == 0) {
                orgCode = YouBianCodeUtil.getSubYouBianCode(parentCode, null);
            } else {
                String subCode = parentList.get(0).getOrgCode();
                orgCode = YouBianCodeUtil.getSubYouBianCode(parentCode, subCode);
            }
            orgType = "1";
        }
        strArray[0] = orgCode;
        strArray[1] = orgType;
        return strArray;
    }

    /**
     * 查询所有的部门数据,以树结构形式返回
     *
     * @return
     */
    public List<SysDepartTree> queryAllDepartAndUser() {
        LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<SysDepart>();
        query.eq(SysDepart::getDelFlag, CommonConstant.DELETE_NO);
        query.orderByAsc(SysDepart::getDepartOrder);
        List<SysDepartDto> list = getMapper().getDepartListAndUser(query);
        List<SysDepartTree> listResult = FindsDepartsChildrenUtil.wrapTreeDataToTreeList2(list);
        return listResult;
    }

    public List<Map<String, Object>> findDepartUserTree(String parentId) {
        List<Map<String, Object>> list = getMapper().findListByParentId(parentId);
        List<Map<String, Object>> children;
        for (Map<String, Object> m : list) {
            children = findDepartUserTree((String) m.get("id"));
            if (children != null && children.size() != 0) {
                children.addAll(sysUserMapper.findUserByDepartId((String) m.get("id")));
            } else {
                children = sysUserMapper.findUserByDepartId((String) m.get("id"));
            }
            m.put("children", children);
        }
        return list;
    }

    /**
     * 根据用户ID查询改用户的部门
     *
     * @param userId
     * @param recursionStatus
     * @return
     */
    public List<String> findDepartIdsByUserId(String userId, Boolean recursionStatus) {
        QueryWrapper<SysUserDepart> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysUserDepart::getUserId, userId);
        List<SysUserDepart> list = sysUserDepartService.list(queryWrapper);
        List<String> departList = new ArrayList<>();
        if (list != null && list.size() > 0) {
            for (SysUserDepart sysUserDept : list) {
                if (recursionStatus) {
                    List<String> subList = new ArrayList<>();
                    getDepartChild(sysUserDept.getDepId(), subList);
                    departList.addAll(subList);
                    departList.add(sysUserDept.getDepId());
                } else {
                    departList.add(sysUserDept.getDepId());
                }
            }
        }
        return departList;
    }

    /**
     * 递归查询子部门id
     */
    private List<String> getDepartChild(String id, List<String> departList) {
        if (departList == null) {
            departList = new ArrayList<>();
        }
        // 根据当前部门id查询所有子部门的id
        QueryWrapper<SysDepart> query = new QueryWrapper<>();
        query.lambda().eq(SysDepart::getDelFlag, CommonConstant.DELETE_NO).eq(SysDepart::getParentId, id);
        List<SysDepart> list = this.list(query);
        if (list != null && list.size() > 0) {
            for (SysDepart dept : list) {
                departList.add(dept.getId());
                // 递归查询
                getDepartChild(dept.getId(), departList);
            }
        }
        return departList;
    }

    /**
     * 递归查询子部门id
     */
    private List<SysDepart> getDepartChildList(String id, List<SysDepart> departList) {
        if (departList == null) {
            departList = new ArrayList<>();
        }
        // 根据当前部门id查询所有子部门的id
        QueryWrapper<SysDepart> query = new QueryWrapper<>();
        query.lambda().eq(SysDepart::getDelFlag, CommonConstant.DELETE_NO).eq(SysDepart::getParentId, id).orderByAsc(SysDepart::getDepartOrder);
        ;
        List<SysDepart> list = this.list(query);
        if (list != null && list.size() > 0) {
            for (SysDepart dept : list) {
                departList.add(dept);
                // 递归查询
                getDepartChildList(dept.getId(), departList);
            }
        }
        return departList;
    }

    /**
     * 递归查询部门
     *
     * @param parentId
     * @param recursion
     * @param selfStatus
     * @return
     */
    public List<SysDepartTree> findDepartInfoParentId(String parentId, Boolean recursion, Boolean selfStatus) {
        List<SysDepart> departList = new ArrayList<>();
        if (recursion) {
            departList = getDepartChildList(parentId, departList);
        } else {
            QueryWrapper<SysDepart> query = new QueryWrapper<>();
            query.lambda().eq(SysDepart::getDelFlag, CommonConstant.DELETE_NO).eq(SysDepart::getParentId, parentId).orderByAsc(SysDepart::getDepartOrder);
            departList = this.list(query);
        }
        if (selfStatus) {
            departList.add(this.getById(parentId));
        }
        List<SysDepartTree> listResult = FindsDepartsChildrenUtil.wrapTreeDataToTreeList0(departList);
        return listResult;
    }

}
